package com.choosefine.base.materiel.common.net;

import com.choosefine.base.materiel.common.exception.ShoppingFrameworkException;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import org.springframework.beans.BeanUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;

import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * API服务请求封装
 */
public class HttpApi {
    /**
     * 字符串转换为 List<String>
     */
    public List<String> convertStringToListString(String source, String delimiter) {
        return Splitter.on(delimiter).trimResults().splitToList(source);
    }

    /**
     * 字符串转换为 List<Long>
     */
    public List<Long> convertStringToListLong(String source, String delimiter) {
        List<String> stringList = Splitter.on(delimiter).trimResults().splitToList(source);
        List<Long> longList = new ArrayList<>();
        for (String s : stringList) {
            longList.add(Long.parseLong(s));
        }
        return longList;
    }

    /**
     * list转换为字符串
     */
    public <T> String converntListToString(List<T> list, String delimiter) {
        return Joiner.on(delimiter).skipNulls().join(list);
    }

    /**
     * Bean实体转化成MultiValueMap
     *
     * @param obj
     * @return
     */
    public MultiValueMap<String, String> beanToMultiValueMap(Object obj) {
        MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
        try {
            Class<?> actualEditable = obj.getClass();
            PropertyDescriptor[] targetPds = BeanUtils.getPropertyDescriptors(actualEditable);
            for (PropertyDescriptor targetPd : targetPds) {
                Method readMethod = targetPd.getReadMethod();
                if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {
                    readMethod.setAccessible(true);
                }
                String name = targetPd.getName();
                Object value = readMethod.invoke(obj);
                if(value != null){
                    if (value instanceof Date) {
                        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        value = simpleDateFormat.format((Date)value);
                    }
                    if(!"class".equals(targetPd.getName()))
                        params.add(targetPd.getName(), value.toString());
                }
            }
        } catch (Exception e) {
            throw new ShoppingFrameworkException("参数转化出错");
        }
        return params;
    }

    /**
     * Bean实体转化成Map
     *
     * @param obj
     * @return
     */
    public Map<String, Object> beanToMap(Object obj) {
        Map<String, Object> params = new HashMap<>(0);
        try {
            Class<?> actualEditable = obj.getClass();
            PropertyDescriptor[] targetPds = BeanUtils.getPropertyDescriptors(actualEditable);
            for (PropertyDescriptor targetPd : targetPds) {
                Method readMethod = targetPd.getReadMethod();
                if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {
                    readMethod.setAccessible(true);
                }
                String name = targetPd.getName();
                Object value = readMethod.invoke(obj);
                if(value != null){
                    if (value instanceof Date) {
                        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        value = simpleDateFormat.format((Date)value);
                    }
                    params.put(targetPd.getName(), value.toString());
                }
            }
        } catch (Exception e) {
            throw new ShoppingFrameworkException("参数转化出错");
        }
        return params;
    }




    /**
     * map参数拼接url
     * @param ymlUrl
     * @param dataMap
     * @return
     */
    public String getUrl(String ymlUrl, Map<String, Object> dataMap) {
        String url = "";
        if (dataMap == null) {
            return ymlUrl;
        }
        url += ymlUrl+ "?";
        for (Map.Entry<String, Object> entry : dataMap.entrySet()) {
            if(entry.getValue()!=null){
                url += entry.getKey() + "=" + entry.getValue() + "&";
            }
        }
        url = removalExcessiveSymbol(url);
        return url;
    }

    /**
     * bean参数拼接url
     * @param ymlUrl
     * @param object
     * @return
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     */
    public String getUrl(String ymlUrl, Object object) throws InvocationTargetException, IllegalAccessException {
        String url = "";
        if (object == null) {
            return ymlUrl;
        }
        url +=ymlUrl + "?";

        Class<?> actualEditable = object.getClass();
        PropertyDescriptor[] targetPds = BeanUtils.getPropertyDescriptors(actualEditable);
        for (PropertyDescriptor targetPd : targetPds) {
            Object value = targetPd.getReadMethod().invoke(object);
            if (!"class".equals(targetPd.getName()) && value != null && !filterParams(value)) {
                url += targetPd.getName() + "=" + value + "&";
            }
        }
        url = removalExcessiveSymbol(url);
        return url;
    }

    /**
     * 传值规定  过滤数字类-1  判断是否过滤
     * @param obj
     * @return
     */
    private boolean filterParams(Object obj){
        boolean flag = false;
        if(getInstanceofType(obj)>4){//判断是否是小数
            flag = "-1.0".equals(obj.toString());
        }else if(getInstanceofType(obj)>0){//判断是否是整数数字
            flag = "-1".equals(obj.toString());
        }
        return flag;
    }

    /**
     * 判断obj是否数字类型
     * @param obj
     * @return
     */
    public Integer getInstanceofType(Object obj){
        int type = 0;
        if(obj instanceof Integer){
            type = 1;
        }else if(obj instanceof Short){
            type = 2;
        }else if(obj instanceof Byte){
            type = 3;
        }else if(obj instanceof Long){
            type = 4;
        }else if(obj instanceof Float){
            type = 5;
        }else if(obj instanceof Double){
            type = 6;
        }

        return type;
    }

    public String removalExcessiveSymbol(String url){
        url = url.substring(0, url.length() - 1);
        url = url.replace("[","");
        url = url.replace("]","");
        return url;
    }
}
